package com.imax.center.service.impl.h3yun;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.imax.center.constant.H3yunApiConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

@Slf4j
@Component
public class H3yunOperate {

    @Value("${h3yun.engine-code}")
    private String engineCode;

    @Value("${h3yun.engine-secret}")
    private String engineSecret;

    @Autowired
    private RestTemplate restTemplate;

    public JSONObject CustomInvoke(String Controller, String ActionName, JSONObject params) {
        try {
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("EngineCode", engineCode);
            headers.set("EngineSecret", engineSecret);
            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("Controller", Controller);
            requestBody.put("ActionName", ActionName);
            requestBody.put("AppCode", H3yunApiConstants.APP_CODE);

            //遍历params
            if (params != null && params.size() > 0) {
                requestBody.putAll(params);
            }

            // 发送请求
            HttpEntity<String> request = new HttpEntity<>(requestBody.toString(), headers);
            String response = restTemplate.postForObject(H3yunApiConstants.BASE_URL, request, String.class);
            // 解析响应
            JSONObject jsonResponse = JSONObject.parseObject(response);
            if (jsonResponse != null && jsonResponse.getBoolean("Successful")) {
                return jsonResponse.getJSONObject("ReturnData").getJSONObject("data");
            }
            String errorMsg = jsonResponse != null ? jsonResponse.getString("ErrorMessage") : "请求失败";
            log.error("失败: {}", errorMsg);
            throw new RuntimeException(errorMsg);
        } catch (Exception e) {
            log.error("异常: ", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    public JSONArray CustomInvokeArray(String Controller, String ActionName, JSONObject params) {
        try {
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("EngineCode", engineCode);
            headers.set("EngineSecret", engineSecret);
            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("Controller", Controller);
            requestBody.put("ActionName", ActionName);
            requestBody.put("AppCode", H3yunApiConstants.APP_CODE);

            //遍历params
            if (params != null && params.size() > 0) {
                requestBody.putAll(params);
            }

            // 发送请求
            HttpEntity<String> request = new HttpEntity<>(requestBody.toString(), headers);
            String response = restTemplate.postForObject(H3yunApiConstants.BASE_URL, request, String.class);
            // 解析响应
            JSONObject jsonResponse = JSONObject.parseObject(response);
            if (jsonResponse != null && jsonResponse.getBoolean("Successful")) {
                return jsonResponse.getJSONObject("ReturnData").getJSONArray("data");
            }
            String errorMsg = jsonResponse != null ? jsonResponse.getString("ErrorMessage") : "请求失败";
            log.error("失败: {}", errorMsg);
            throw new RuntimeException(errorMsg);
        } catch (Exception e) {
            log.error("异常: ", e);
            throw new RuntimeException(e.getMessage());
        }
    }
    
    public JSONObject CreateBizObject(String SchemaCode, JSONObject bizObject) {
        try {
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("EngineCode", engineCode);
            headers.set("EngineSecret", engineSecret);
            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("ActionName", H3yunApiConstants.ACTION_CREATE_BIZ_OBJECT);
            requestBody.put("SchemaCode", SchemaCode);
            requestBody.put("BizObject", bizObject.toString());
            requestBody.put("IsSubmit", "true");
            // 发送请求
            HttpEntity<String> request = new HttpEntity<>(requestBody.toString(), headers);
            String response = restTemplate.postForObject(H3yunApiConstants.BASE_URL, request, String.class);
            // 解析响应
            JSONObject jsonResponse = JSONObject.parseObject(response);
            if (jsonResponse != null && jsonResponse.getBoolean("Successful")) {
                return jsonResponse.getJSONObject("ReturnData");
            }
            String errorMsg = jsonResponse != null ? jsonResponse.getString("ErrorMessage") : "请求失败";
            log.error("保存失败: {}", errorMsg);
            throw new RuntimeException(errorMsg);
        } catch (Exception e) {
            log.error("保存信息异常: ", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    public JSONObject UpdateBizObject(String SchemaCode, String BizObjectId, JSONObject bizObject) {
        try {
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("EngineCode", engineCode);
            headers.set("EngineSecret", engineSecret);
            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("ActionName", H3yunApiConstants.ACTION_UPDATE_BIZ_OBJECT);
            requestBody.put("SchemaCode", SchemaCode);
            requestBody.put("BizObjectId", BizObjectId);
            requestBody.put("BizObject", bizObject.toString());
            // 发送请求
            HttpEntity<String> request = new HttpEntity<>(requestBody.toString(), headers);
            String response = restTemplate.postForObject(H3yunApiConstants.BASE_URL, request, String.class);
            // 解析响应
            JSONObject jsonResponse = JSONObject.parseObject(response);
            if (jsonResponse != null && jsonResponse.getBoolean("Successful")) {
                return jsonResponse.getJSONObject("ReturnData");
            }
            String errorMsg = jsonResponse != null ? jsonResponse.getString("ErrorMessage") : "请求失败";
            throw new RuntimeException(errorMsg);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public JSONArray LoadBizObjects(String SchemaCode, Map<String, Object> queryParams) {
        return this.LoadBizObjects(SchemaCode, queryParams, null, false);
    }

    public JSONArray LoadBizObjects(String SchemaCode, Map<String, Object> queryParams, boolean loadAll) {
        return this.LoadBizObjects(SchemaCode, queryParams, null, loadAll);
    }

    public JSONArray LoadBizObjects(String SchemaCode, Map<String, Object> queryParams, Integer pageNo, Integer pageSize) {
        return this.LoadBizObjects(SchemaCode, queryParams, null, 0, pageSize, false, 2);
    }
    
    /**
     * 加载业务对象
     * 
     * @param SchemaCode 业务对象模式编码
     * @param queryParams 查询参数
     * @param operator Operator运算符：0=大于，1=大于等于，2=等于，3=小于等于，4=小于，5=不等于，6=在某个范围内，7=不在某个范围内，8=like查询
     * @return 业务对象数组
     */
    public JSONArray LoadBizObjects(String SchemaCode, Map<String, Object> queryParams, int operator) {
        return this.LoadBizObjects(SchemaCode, queryParams, null, false, operator);
    }
    
    public JSONArray LoadBizObjects(String SchemaCode, Map<String, Object> queryParams, String ReturnItems) {
        return this.LoadBizObjects(SchemaCode, queryParams, ReturnItems, false);
    }
    
    /**
     * 加载业务对象
     * 
     * @param SchemaCode 业务对象模式编码
     * @param queryParams 查询参数
     * @param ReturnItems 返回项，逗号分隔的字段名
     * @param operator Operator运算符：0=大于，1=大于等于，2=等于，3=小于等于，4=小于，5=不等于，6=在某个范围内，7=不在某个范围内，8=like查询
     * @return 业务对象数组
     */
    public JSONArray LoadBizObjects(String SchemaCode, Map<String, Object> queryParams, String ReturnItems, int operator) {
        return this.LoadBizObjects(SchemaCode, queryParams, ReturnItems, false, operator);
    }
    
    public JSONArray LoadBizObjects(String SchemaCode, Map<String, Object> queryParams, String ReturnItems, boolean loadAll) {
        return this.LoadBizObjects(SchemaCode, queryParams, ReturnItems, 0, 500, loadAll, 2);
    }
    
    /**
     * 加载业务对象
     * 
     * @param SchemaCode 业务对象模式编码
     * @param queryParams 查询参数
     * @param ReturnItems 返回项，逗号分隔的字段名
     * @param loadAll 是否加载所有匹配的数据
     * @param operator Operator运算符：0=大于，1=大于等于，2=等于，3=小于等于，4=小于，5=不等于，6=在某个范围内，7=不在某个范围内，8=like查询
     * @return 业务对象数组
     */
    public JSONArray LoadBizObjects(String SchemaCode, Map<String, Object> queryParams, String ReturnItems, boolean loadAll, int operator) {
        return this.LoadBizObjects(SchemaCode, queryParams, ReturnItems, 0, 500, loadAll, operator);
    }
    
    /**
     * 加载业务对象
     * 
     * @param SchemaCode 业务对象模式编码
     * @param queryParams 查询参数
     * @param ReturnItems 返回项，逗号分隔的字段名
     * @param FromRowNum 起始行号
     * @param pageSize 每页大小
     * @param loadAll 是否加载所有匹配的数据
     * @return 业务对象数组
     */
    public JSONArray LoadBizObjects(String SchemaCode, Map<String, Object> queryParams, String ReturnItems, int FromRowNum, int pageSize, boolean loadAll) {
        return this.LoadBizObjects(SchemaCode, queryParams, ReturnItems, FromRowNum, pageSize, loadAll, 2);
    }
    
    /**
     * 加载业务对象
     * 
     * @param SchemaCode 业务对象模式编码
     * @param queryParams 查询参数
     * @param ReturnItems 返回项，逗号分隔的字段名
     * @param FromRowNum 起始行号
     * @param pageSize 每页大小
     * @param loadAll 是否加载所有匹配的数据
     * @param operator Operator运算符：0=大于，1=大于等于，2=等于，3=小于等于，4=小于，5=不等于，6=在某个范围内，7=不在某个范围内，8=like查询
     * @return 业务对象数组
     */
    public JSONArray LoadBizObjects(String SchemaCode, Map<String, Object> queryParams, String ReturnItems, int FromRowNum, int pageSize, boolean loadAll, int operator) {
        try {
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("EngineCode", engineCode);
            headers.set("EngineSecret", engineSecret);
            
            // 结果集
            JSONArray allResults = new JSONArray();
            
            int fromRowNum = FromRowNum;
            int toRowNum = fromRowNum + pageSize;
            boolean hasMorePages = true;
            int totalCount = 0;
            
            while (hasMorePages) {
                // 构建查询条件
                JSONObject matcher = new JSONObject();
                matcher.put("Type", "And");
                JSONArray matchers = new JSONArray();
                String filterStr = "{\"FromRowNum\": " + fromRowNum + ",\"RequireCount\": true,\"ReturnItems\": [], \"SortByCollection\": [],\"ToRowNum\": " + toRowNum + ", \"Matcher\": {\"Type\": \"And\", \"Matchers\": [{\"Type\":\"And\",\"Matchers\":[]}]}}";
                
                //如果ReturnItems不为空，则将ReturnItems转换为JSONArray
                if (ReturnItems != null && !StringUtils.isEmpty(ReturnItems) && !ReturnItems.equals("*")) {
                    ReturnItems = ReturnItems.replaceAll(" ", "");
                    JSONArray returnItems = new JSONArray();
                    String[] items = ReturnItems.split(",");
                    returnItems.addAll(Arrays.asList(items));
                    filterStr = filterStr.replace("ReturnItems\": [],", "ReturnItems\": " + returnItems.toString() + ",");
                }
                
                // 遍历查询参数，构建查询条件
                if (queryParams != null) {
                    for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
                        String fieldName = entry.getKey();
                        Object fieldValue = entry.getValue();

                        if (fieldValue != null && !StringUtils.isEmpty(fieldValue.toString())) {
                            JSONObject fieldMatcher = new JSONObject();
                            fieldMatcher.put("Type", "And");

                            JSONArray fieldMatchers = new JSONArray();
                            JSONObject itemMatcher = new JSONObject();
                            itemMatcher.put("Type", "Item");
                            itemMatcher.put("Name", fieldName);
                            itemMatcher.put("Operator", operator); // 使用传入的运算符
                            itemMatcher.put("Value", fieldValue.toString());

                            fieldMatchers.add(itemMatcher);
                            fieldMatcher.put("Matchers", fieldMatchers);
                            matchers.add(fieldMatcher);
                        }
                    }
                    matcher.put("Matchers", matchers);
                    // 构建Filter参数
                    JSONObject filter = new JSONObject();
                    filter.put("FromRowNum", fromRowNum);
                    filter.put("ToRowNum", toRowNum);
                    filter.put("RequireCount", true);
                    //将使用,分割的ReturnItems字符串转换为JSONArray
                    JSONArray returnItems = new JSONArray();
                    if (ReturnItems != null && !StringUtils.isEmpty(ReturnItems) && !ReturnItems.equals("*")) {
                        ReturnItems = ReturnItems.replaceAll(" ", "");
                        String[] items = ReturnItems.split(",");
                        returnItems.addAll(Arrays.asList(items));
                    }
                    filter.put("ReturnItems", returnItems);
                    filter.put("SortByCollection", new JSONArray());
                    filter.put("Matcher", matcher);
                    filterStr = filter.toString();
                }

                // 构建请求体
                JSONObject requestBody = new JSONObject();
                requestBody.put("ActionName", H3yunApiConstants.ACTION_LOAD_BIZ_OBJECTS);
                requestBody.put("SchemaCode", SchemaCode);
                requestBody.put("Filter", filterStr);

                // 发送请求
                HttpEntity<String> request = new HttpEntity<>(requestBody.toString(), headers);
                String response = restTemplate.postForObject(H3yunApiConstants.BASE_URL, request, String.class);

                // 解析响应
                JSONObject jsonResponse = JSONObject.parseObject(response);
                if (jsonResponse != null && jsonResponse.getBoolean("Successful")) {
                    JSONObject returnData = jsonResponse.getJSONObject("ReturnData");
                    if (returnData != null) {
                        // 获取当前页数据
                        JSONArray bizObjectArray = returnData.getJSONArray("BizObjectArray");
                        if (bizObjectArray != null && !bizObjectArray.isEmpty()) {
                            // 将当前页数据添加到结果集
                            allResults.addAll(bizObjectArray);
                        }
                        
                        // 如果不需要加载所有数据，则直接返回第一页结果
                        if (!loadAll) {
                            return bizObjectArray;
                        }
                        
                        // 获取总记录数
                        totalCount = returnData.getIntValue("TotalCount");
                        log.info("查询业务对象总记录数: {}", totalCount);
                        
                        // 判断是否还有更多页
                        if (allResults.size() >= totalCount || bizObjectArray == null || bizObjectArray.isEmpty()) {
                            hasMorePages = false;
                        } else {
                            // 移动到下一页
                            fromRowNum = toRowNum;
                            toRowNum = Math.min(fromRowNum + pageSize, totalCount);
                        }
                    } else {
                        hasMorePages = false;
                    }
                } else {
                    String errorMsg = jsonResponse != null ? jsonResponse.getString("ErrorMessage") : "请求失败";
                    throw new RuntimeException(errorMsg);
                }
            }
            
            return allResults;
        } catch (Exception e) {
            log.error("加载业务对象异常: ", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    public JSONObject RemoveBizObject(String SchemaCode, String BizObjectId) {
        try {
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("EngineCode", engineCode);
            headers.set("EngineSecret", engineSecret);
            
            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("ActionName", H3yunApiConstants.ACTION_REMOVE_BIZ_OBJECT);
            requestBody.put("SchemaCode", SchemaCode);
            requestBody.put("BizObjectId", BizObjectId);
            
            // 发送请求
            HttpEntity<String> request = new HttpEntity<>(requestBody.toString(), headers);
            String response = restTemplate.postForObject(H3yunApiConstants.BASE_URL, request, String.class);
            
            // 解析响应
            JSONObject jsonResponse = JSONObject.parseObject(response);
            if (jsonResponse != null && jsonResponse.getBoolean("Successful")) {
                return jsonResponse.getJSONObject("ReturnData");
            }
            String errorMsg = jsonResponse != null ? jsonResponse.getString("ErrorMessage") : "删除失败";
            log.error("删除业务对象失败: {}", errorMsg);
            throw new RuntimeException(errorMsg);
        } catch (Exception e) {
            log.error("删除业务对象异常: ", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    public JSONObject RemoveBizObjects(String SchemaCode, List<String> BizObjectIds) {
        try {
            // 记录批量删除结果
            JSONObject batchResult = new JSONObject();
            JSONArray successIds = new JSONArray();
            JSONArray failIds = new JSONArray();
            List<String> errorMessages = new ArrayList<>();
            
            // 循环调用单条删除方法
            for (String bizObjectId : BizObjectIds) {
                try {
                    JSONObject result = RemoveBizObject(SchemaCode, bizObjectId);
                    successIds.add(bizObjectId);
                } catch (Exception e) {
                    failIds.add(bizObjectId);
                    errorMessages.add(e.getMessage());
                    log.error("删除业务对象失败, SchemaCode: {}, BizObjectId: {}, 错误: {}", 
                              SchemaCode, bizObjectId, e.getMessage());
                }
            }
            
            // 构建返回结果
            batchResult.put("SuccessIds", successIds);
            batchResult.put("FailIds", failIds);
            batchResult.put("ErrorMessages", errorMessages);
            batchResult.put("TotalCount", BizObjectIds.size());
            batchResult.put("SuccessCount", successIds.size());
            batchResult.put("FailCount", failIds.size());
            
            // 如果全部失败则抛出异常
            if (successIds.isEmpty() && !failIds.isEmpty()) {
                throw new RuntimeException("所有业务对象删除失败: " + String.join("; ", errorMessages));
            }
            
            return batchResult;
        } catch (Exception e) {
            log.error("批量删除业务对象异常: ", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 上传附件到氚云
     * 
     * @param schemaCode 表单编码
     * @param filePropertyName 表单控件编码
     * @param bizObjectId 表单ObjectId值
     * @param file 要上传的文件
     * @return 上传成功后的附件ID（AttachmentId）
     */
    public String uploadAttachment(String schemaCode, String filePropertyName, String bizObjectId, MultipartFile file) {
        try {
            log.info("开始上传附件到氚云, SchemaCode: {}, FilePropertyName: {}, BizObjectId: {}", 
                     schemaCode, filePropertyName, bizObjectId);
            
            // 构建上传URL
            String uploadUrl = H3yunApiConstants.FILE_UPLOAD_URL +
                              "?SchemaCode=" + schemaCode +
                              "&FilePropertyName=" + filePropertyName +
                              "&BizObjectId=" + bizObjectId;
            
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            headers.set("EngineCode", engineCode);
            headers.set("EngineSecret", engineSecret);
            
            // 构建请求体 - 文件部分
            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            ByteArrayResource fileResource = new ByteArrayResource(file.getBytes()) {
                @Override
                public String getFilename() {
                    return file.getOriginalFilename();
                }
            };
            body.add("file", fileResource);
            
            // 发送请求
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
            String response = restTemplate.postForObject(uploadUrl, requestEntity, String.class);
            
            // 解析响应
            JSONObject jsonResponse = JSONObject.parseObject(response);
            if (jsonResponse != null && jsonResponse.getBoolean("Successful")) {
                JSONObject returnData = jsonResponse.getJSONObject("ReturnData");
                String attachmentId = returnData.getString("AttachmentId");
                log.info("附件上传成功, AttachmentId: {}", attachmentId);
                return attachmentId;
            }
            
            String errorMsg = jsonResponse != null ? jsonResponse.getString("ErrorMessage") : "上传失败";
            log.error("附件上传失败: {}", errorMsg);
            throw new RuntimeException(errorMsg);
        } catch (Exception e) {
            log.error("上传附件异常: ", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 获取缩略图URL
     * 
     * @param fileId 文件ID
     * @return 缩略图URL
     */
    public String getThumbnailUrl(String fileId) {
        try {
            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("EngineCode", engineCode);
            headers.set("EngineSecret", engineSecret);
            
            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("Controller", "Common");
            requestBody.put("ActionName", "getThumbnailUrl");
            requestBody.put("AppCode", H3yunApiConstants.APP_CODE);
            requestBody.put("fileId", fileId);
            
            // 发送请求
            HttpEntity<String> request = new HttpEntity<>(requestBody.toString(), headers);
            String response = restTemplate.postForObject(H3yunApiConstants.BASE_URL, request, String.class);
            
            // 解析响应
            JSONObject jsonResponse = JSONObject.parseObject(response);
            if (jsonResponse != null && jsonResponse.getBoolean("Successful")) {
                JSONObject data = jsonResponse.getJSONObject("ReturnData").getJSONObject("data");
                return data.getString("url");
            }
            String errorMsg = jsonResponse != null ? jsonResponse.getString("ErrorMessage") : "获取缩略图URL失败";
            log.error("获取缩略图URL失败: {}", errorMsg);
            throw new RuntimeException(errorMsg);
        } catch (Exception e) {
            log.error("获取缩略图URL异常: ", e);
            throw new RuntimeException(e.getMessage());
        }
    }

}